//------------------------------------------------------------------
//  POLY.h 
//------------------------------------------------------------------
#define DBLBITS		2*NUMBITS
#define DBLWORD		(DBLBITS/WORDSIZE)
#define	DBLSHIFT	(DBLBITS%WORDSIZE)
#define	MAXDBL		(DBLWORD+1)
#define	DERIVMASK	0x55555555
#define DBLLOOP(i)	for(i=0; i<MAXDBL; i++)
typedef struct {
	ELEMENT		e[MAXDBL];
} DBLFIELD;
//-------------------------------------------------------------------
//  polynomial
//-------------------------------------------------------------------
void poly_rot_left(FIELD2N* a);
void poly_rot_right(FIELD2N* a);
void poly_mul_shift(DBLFIELD* a);
void poly_null(FIELD2N* a);
void poly_dblnull(DBLFIELD* a);
void poly_copy(FIELD2N* from, FIELD2N* to);
void poly_mul_partial(FIELD2N* a, FIELD2N* b, DBLFIELD* c);
void div_shift(DBLFIELD* a);
INDEX degreeof(ELEMENT* t, INDEX dim);
void poly_div(DBLFIELD* top, FIELD2N* bottom, FIELD2N* quotient, FIELD2N* remainder);
void poly_gcd(FIELD2N* u, FIELD2N* v, FIELD2N* gcd);
INDEX irreducible(FIELD2N* v);
//-------------------------------------------------------------------
//  modular
//-------------------------------------------------------------------
void poly_mod_add(FIELD2N* a, FIELD2N* b, FIELD2N* c, FIELD2N* p);
void poly_mod_sub(FIELD2N* a, FIELD2N* b, FIELD2N* c, FIELD2N* p);
void poly_mod_mul(FIELD2N *a, FIELD2N* b, FIELD2N* c, FIELD2N* p);
void poly_mod_inv(FIELD2N* a, FIELD2N* inverse, FIELD2N* p);
//-------------------------------------------------------------------
//  Montgomery
//-------------------------------------------------------------------
void poly_mon_mod_mul(FIELD2N* a, FIELD2N* b, FIELD2N* c, FIELD2N* p);
void poly_mon_mod_div(FIELD2N* a, FIELD2N* b, FIELD2N* c, FIELD2N* p);
void poly_to_mon(FIELD2N* a, FIELD2N* b, FIELD2N* p);
void mon_to_poly(FIELD2N* a, FIELD2N* b, FIELD2N* p);
//-------------------------------------------------------------------
//  Others
//-------------------------------------------------------------------
void sngltodbl(FIELD2N* from, DBLFIELD* to);
void dbltosngl(DBLFIELD* from, FIELD2N* to);
INDEX log_2(ELEMENT x);
void mul_x_mod(FIELD2N* u, FIELD2N* v, FIELD2N* w);
void print_poly(FIELD2N* a);
void wfile_poly(FIELD2N* a, char* filename);
void afiel_poly(FIELD2N* a, char* filename);
